<?xml version="1.0" encoding="UTF-8"?>
<html>
    <head>
        <link type="text/css" rel="stylesheet" href="./css/template.css" />
        <link type="text/css" rel="stylesheet" href="./css/SyntaxHighlighter.css" />
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Manipulating XML with JDOM</title>
        <script language="javascript" src="./js/shInit.js" />
        <script language="javascript" src="./js/shCore.js" />
        <script language="javascript" src="./js/shBrushCpp.js" />
        <script language="javascript" src="./js/shBrushCSharp.js" />
        <script language="javascript" src="./js/shBrushCss.js" />
        <script language="javascript" src="./js/shBrushDelphi.js" />
        <script language="javascript" src="./js/shBrushJava.js" />
        <script language="javascript" src="./js/shBrushJScript.js" />
        <script language="javascript" src="./js/shBrushPhp.js" />
        <script language="javascript" src="./js/shBrushPython.js" />
        <script language="javascript" src="./js/shBrushRuby.js" />
        <script language="javascript" src="./js/shBrushSql.js" />
        <script language="javascript" src="./js/shBrushVb.js" />
        <script language="javascript" src="./js/shBrushXml.js" />
        <keywords>xml,jdom</keywords>
        <author>Nicolas CYNOBER</author>
    </head>
    <body>
        <div class="chapter">
            <h2>Introduction</h2>
            <div class="subChapter">
                <p>JDOM is a Java language API developed independently from Sun Microsystems. It is designed for easier XML manipulation that classical APIs. It's use is practical for all Java developers and is based on the Sun XML collections.</p>
                <div class="quote">
                    In general we tend to prefer to avoid adding new APIs to the Java platform which replicate the functionality of existing APIs.
					However JDOM does appear to be significantly easier to use than the earlier APIs, so we believe it will be a useful addition to the platform.
                    <div class="quote_author">Sun Microsystems (Comment on the JSR-102 Approval Ballot)</div>
                </div>
                <p>
                    The official documentation is available
                    <a href="http://www.jdom.org/docs/apidocs/" target="_blank">here</a>
                    . As of 23/01/2008 JDOM is available in version 1.1 and compatible with versions 2 and above of the JDK. You can download the binaries 
					<a href="http://www.jdom.org/dist/binary/" target="_blank">here.</a>
                    .
                </p>
                <h3>Goal of this article</h3>
                <p>In this article you will learn to manipulate XML data with the Java language and the JDOM API. We will see the possibilities offered by this API through some simple examples. We'll learn how to create a simple XML document, how to traverse it's tree, modify it's contents, etc.</p>
            </div>
        </div>
        <div class="chapter">
            <h2>Origins of JDOM</h2>
            <div class="subChapter">
                <h3>Description of SAX</h3>
                <p>SAX is the acronym for Simple API for XML. This type of parser uses events to control the treatment of an XML file. A handler must implement the methods defined by an interface of the API to supply the actions to perform: depending on the fired events the parser will call these methods.</p>
                <p>
					For more information about SAX visit
                    <a href="http://www.saxproject.org/" target="_blank">the official site</a>
                    .
                </p>
                <p>JDOM uses SAX to parse XML files.</p>
                <h3>Description of DOM</h3>
                <p>DOM is the acronym for Document Object Model. It's a W3C specification proposing an API that can model, traverse and manipulate an XML document. The principle role of DOM is to give a representation in memory of an XML document in the shape of a tree of objects and allow the manipulation (traversal, search and update) of this tree.</p>
                <p>
					From this model DOM allows traversal of the document but also it's modification. This is the most interesting aspect of DOM. DOM is defined to be independent of the language in which it's implemented. It's merely a specification that can be implemented by third parties.
                    <b>DOM is therefore not unique to Java</b>
                    .
                </p>
                <p>
					The most popular DOM parser for Java is Xerces that you can find
                    <a href="http://xml.apache.org/">here</a>
                    .
                </p>
                <p>JDOM uses DOM to manipulate the elements of a specific Document Model Object created with a SAX based constructor. You can therefore create documents, navigate their structure add modify or delete elements or data.</p>
                <h3>Why JDOM?</h3>
                <p>
					A logical question to ask ourselves at this point of the article,
                    <b>What does JDOM offer us?</b>
                </p>
                <p>
                    <b>Simplicity!</b>
					It is in truth very laborious to develop complex applications around XML with DOM, which, remember, wasn't developed specifically for JAVA. Let us now look at all the possibilities JDOM offers us through a series of short examples.
                </p>
            </div>
        </div>
        <div class="chapter">
            <h2>Creating an XML file with JDOM</h2>
            <div class="subChapter">
                <h3>Importing the JDOM API</h3>
                <p>
					You must first download the current version of JDOM from 
                    <a href="http://www.jdom.org/dist/binary/" target="_blank">here</a>
                    . Next import /build/jdom.jar into your project.
                </p>
                <h3>Creating a simple tree</h3>
                <p>The constitution of an XML file from nothing is very simple. You need simply construct each element and add them one by one in a logical manner. A node is an Element.</p>
                <p>We start by creating a JDOM1 class that will create the following tree:</p>

                <textarea name="code" class="xml">
                    <people>
                        <student class="P2">
                            <name>CynO</name>
                            <student>
                                <people />
                            </student>
                        </student>
                    </people>
                </textarea>
                <textarea name="code" class="java">import java.io.*;
					import org.jdom.*;
					import org.jdom.output.*;
					public class JDOM1
					{
					//We will start our tree by creating the XML root
					//which will be 'people' here.
					static Element root = new Element("people");
					//Here we create a new JDOM Document based on the root we just created
					static org.jdom.Document document = new Document(root);
					public static void main(String[] args)
					{
					//We create a new student Element and we add it
					//as an Element of root
					Element student = new Element("student");
					root.addContent(student);
					//We create a new class attribute and we add it to student
					//with the setAttribute method
					Attribute classe = new Attribute("class","P2");
					student.setAttribute(class);
					//We create a new name Element and we assign him some text
					//then add it as an Element of student
					Element name = new Element("name");
					name.setText("CynO");
					student.addContent(name);
					//The two following lines will be explained in section 2.3
					display();
					save("Exercice 1.xml");
					}
					}</textarea>
                <h3>Displaying and saving your XML file</h3>
                <p>We're going to display then save our tree, for this we'll use a single class: XMLOutputter() that takes as an argument an output Format</p>
                <p>
					As well as three default formats the Format class contains many methods to specialize your serialisation. You can find a description of these methods
                    <a href="http://www.jdom.org/docs/apidocs/org/jdom/output/Format.html" target="_blank">here</a>
                    .
                </p>
                <textarea name="code" class="java">//Add these two methods to our JDOM class
					static void display()
					{
					try
					{
					//Here we use a classical display method with getPrettyFormat()
					XMLOutputter out = new XMLOutputter(Format.getPrettyFormat());
					out.output(document, System.out);
					}
					catch (java.io.IOException e){}
					}
					static void save(String file)
					{
					try
					{
					//Here we use a classical display method with getPrettyFormat()
					XMLOutputter out = new XMLOutputter(Format.getPrettyFormat());
					//Note that you need merely create an instance of FileOutputStream
					//with the name of the file in argument to serialize the data
					out.output(document, new FileOutputStream(file));
					}
					catch (java.io.IOException e){}
					}</textarea>
                <p>After compilation here is the output. You can check the content of the 'Exercise 1.xml' file in the folder containing your class.</p>
                <textarea name="code" class="xml">
                    &lt;?xml version="1.0" encoding="UTF-8"?&gt;
                    <people>
                        <student class="P2">
                            <name>CynO</name>
                        </student>
                    </people>
                </textarea>
                <p>In the third section we'll see how to work on an existing document, traverse it's tree and filter it's elements.</p>
            </div>
        </div>
        <div class="chapter">
            <h2>Traversing an XML file</h2>
            <div class="subChapter">
                <h3>Parsing an XML file</h3>
                <p>Parsing an XML file is the transformation of an XML file into a JDOM tree. For this we will use the SAXBuilder constructer, based as it's name suggests on the SAX API.</p>
                <p>First create the following file in the folder containing the JDOM2 class you will later write:</p>
                <p>
                    <b>Exercice 2.xml</b>
                </p>
                <textarea name="code" class="xml">
                    &lt;?xml version="1.0" encoding="UTF-8"?&gt;
                    <people>
                        <student classe="P2">
                            <name>CynO</nom>
                            <firstnames>
                                <firstname>Nicolas</firstname>
                                <firstname>Laurent</firstname>
                            </firstnames>
                        </student>
                        <student class="P1">
                            <name>Superwoman</name>
                        </student>
                        <student class="P1">
                            <name>Don Corleone</name>
                        </student>
                    </people>
                </textarea>
                <p>Our objective here is to first display the name of all the students. For this we will create a new class: JDOM2.</p>
                <textarea name="code" class="java">import java.io.*;
					import org.jdom.*;
					import org.jdom.input.*;
					import org.jdom.filter.*;
					import java.util.List;
					import java.util.Iterator;
					public class JDOM2
					{
					static org.jdom.Document document;
					static Element root;
					public static void main(String[] args)
					{
					//We create a new SAXBuilder parser instance
					SAXBuilder sxb = new SAXBuilder();
					try
					{
					//We create a new JDOM document with the xml file in arguments
					//The parsing is complete
					document = sxb.build(new File("Exercice 2.xml"));
					}
					catch(Exception e){}
					//We initialise a new root element with the document's root element
					root = document.getRootElement();
					//Method defined in section 3.1 of the article
					displayALL();
					}
					}</textarea>
                <h3>Traversing a tree</h3>
                <p>In this function we will use two classes from java.util</p>
                <ul>
                    <li>
                        <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/List.html" target="_blank">java.util.List</a>
                    </li>
                    <li>
                        <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/Iterator.html" target="_blank">java.util.Iterator</a>
                    </li>
                </ul>
                <p>We are going to create a list based on the student nodes of our tree then traverse it with an iterator.</p>
                <textarea name="code" class="java">//Add these methods to the JDOM2 class
					static void displayALL()
					{
					//We create a list containing all the student nodes of the root Element
					List listStudents = root.getChildren("student");
					//We create an iterator on our list
					Iterator i = listStudents.iterator();
					while(i.hasNext())
					{
					//We recreate the current Element on every loop to
					//be able to use the Element methods like
					//selectioning a child element, modify text, etc.
					Element current = (Element)i.next();
					//We display the name of the current element
					System.out.println(current.getChild("name").getText());
					}
					}</textarea>
                <p>On compilation you should see 'CynO', 'Superwoman' and 'Don Corleone' displayed</p>
                <h3>Filtering Elements</h3>
                <p>Our new objective is to display the class of the students whose first name is Laurent and name is CynO.</p>
                <p>The only filters we have used so far were directly implemented by the methods we were using.</p>
                <textarea name="code" class="java">List listStudents = root.getChildren("student")</textarea>
                <p>Allowed us to filter the child elements of root according to their name.</p>
                <p>You will notice that we only had student elements anyway, so the exercise was purely academic.</p>
                <p>The filters allow selections of Elements according to multiple criteria. We will now create a filter that will only return Elements containing:</p>
                <ul>
                    <li>A 'name' child element with the value 'CynO'</li>
                    <li>A 'firstname' child element containing the value 'Laurent'</li>
                </ul>
                <p>Once the filter is created we can create a list corresponding to it's criteria.</p>
                <textarea name="code" class="java">//Add this method to the JDOM2 class
					//Replace the displayAll line by displayFilter
					static void displayFiltre()
					{
					//Here we create a new filter
					Filter filter = new Filter()
					{
					//We define the properties of the filter
					//with the matches method
					public boolean matches(Object ob)
					{
					//First check: we check the objects
					//That are filtered are indeed Elements
					if(!(ob instanceof Element)){return false;}
					//We now create an Element on which we will perform the 
					//Following checks:
					Element element = (Element)ob;
					//We create two variables that will let us check the 
					//name and firstname variables.
					int verifName= 0;
					int verifFirstname= 0;
					//Second check: we check that the name is "CynO"
					if(element.getChild("name").getTextTrim().equals("CynO"))
					{
					verifNom = 1;
					}
					//Third check: we check that CynO has the firstname "Laurent"
					//We start by checking that the person has a firstname
					//Indeed our XML file has some students with no firstname.
					Element firstnames = element.getChild("firstnames");
					if(firstnames==null){return false;}
					//We make a list of all the firstnames
					List listFirstnames = firstnames.getChildren("firstname");
					//We check by traversing the list of firstnames
					//See 3.1, traversing a tree
					Iterator i = listFirstnames.iterator();
					while(i.hasNext())
					{
					Element current = (Element)i.next();
					if(current.getText().equals("Laurent"))
					{
					verifFirstname = 1;
					}
					}
					//If our confitions are filled we return true, otherwise false
					if(verifName == 1 &amp;&amp; verifFirstname == 1)
					{
					return true;
					}
					return false;
					}
					};//End of filter
					//getContent will use our filter to create a list of students filling
					//Our criteria
					List result = root.getContent(filter);
					//Finally we display the class of all the elements of our list
					Iterator i = result.iterator();
					while(i.hasNext())
					{
					Element current = (Element)i.next();
					System.out.println(current.getAttributeValue("class"));
					}
					}</textarea>
                <p>On compilation you should see 'P2' displayed on your screen.</p>
                <p>The power of this tool resides in it's capacity to be used at any moment by any Element of your tree.</p>
                <p>
					In our example we used our JDOM filter like a search engine. It's quite possible to create dynamic filters according to your needs. To learn more about the Filter class go 
                    <a href="http://www.jdom.org/docs/apidocs/org/jdom/filter/package-summary.html" target="_blank">here</a>
                    .
                </p>
            </div>
        </div>
        <div class="chapter">
            <h2>Modifying a JDOM tree</h2>
            <div class="subChapter">
                <h3>Modifying elements</h3>
                <p>Up to now we used selection methods on our Elements but there are also many methods used to replace or add different object to our tree.</p>
                <p>Follows a list of all the most useful modification methods:</p>
                <table width="100%" border="1">
                    <tbody>
                        <tr>
                            <td width="12%">
                                <strong>Name</strong>
                            </td>
                            <td width="26%">Overload arguments</td>
                            <td width="62%">Description</td>
                        </tr>
                        <tr valign="top">
                            <td>
                                <strong>addContent</strong>
                            </td>
                            <td>
                                <em>Collection</em>
                                ,
                                <em>String</em>
                                ou
                                <em>Content</em>
                                , i.e
								an
                                <em>Element</em>
								Or anything else that can be contained in a node.
                            </td>
                            <td>Adds the content of the argument to the end of the contents of an Element
								You can specify an index to insert it at the desired position.</td>
                        </tr>
                        <tr valign="top">
                            <td>
                                <strong>clone</strong>
                            </td>
                            <td> </td>
                            <td>Returns a clone of an element</td>
                        </tr>
                        <tr valign="top">
                            <td>
                                <strong>cloneContent</strong>
                            </td>
                            <td> </td>
                            <td>Copies only the content of the Element</td>
                        </tr>
                        <tr valign="top">
                            <td>
                                <strong>removeAttribute</strong>
                            </td>
                            <td>
                                <em>Attribut</em>
                                or name of the attribute (
                                <em>String</em>
                                )
                            </td>
                            <td>Removes an attribute from an Element</td>
                        </tr>
                        <tr valign="top">
                            <td>
                                <strong>removeChild</strong>
                            </td>
                            <td>
                                name of child node (
                                <em>String</em>
                                )
                            </td>
                            <td>Removes the first child with the given name</td>
                        </tr>
                        <tr valign="top">
                            <td>
                                <strong>removeChildren</strong>
                            </td>
                            <td>
                                Name of child nodes (
                                <em>String</em>
                                )
                            </td>
                            <td>Removes all children with the given name</td>
                        </tr>
                        <tr valign="top">
                            <td>
                                <strong>removeContent</strong>
                            </td>
                            <td>
                                <em>Content</em>
                                ,
                                <em>Index</em>
                                ou
                                <em>Filter</em>
                            </td>
                            <td>Deletes the entire node given as argument
								or by position. removeContent also accepts filters like getContent
								seen previously.</td>
                        </tr>
                        <tr valign="top">
                            <td>
                                <strong>setAttributes</strong>
                            </td>
                            <td>
                                <em>Attribut</em>
                                Or name of the attribute and it's value (
                                <em>String, String</em>
                                )
                            </td>
                            <td>This method allows both creation
								and modification of existing attributes.</td>
                        </tr>
                        <tr valign="top">
                            <td>
                                <strong>setContent</strong>
                            </td>
                            <td>
                                <em>Content</em>
                            </td>
                            <td>Replaces the content of an element. An index can be specified
								if one does not wish the replace everything.</td>
                        </tr>
                        <tr valign="top">
                            <td>
                                <strong>setName</strong>
                            </td>
                            <td>
                                New element name (
                                <em>String</em>
                                )
                            </td>
                            <td>Change the name of an Element</td>
                        </tr>
                        <tr valign="top">
                            <td>
                                <strong>setText</strong>
                            </td>
                            <td>
                                New text to insert (
                                <em>String</em>
                                )
                            </td>
                            <td>Change the text contained by the Element. &lt;element&gt;TEXT&lt;/element&gt;</td>
                        </tr>
                        <tr valign="top">
                            <td>
                                <strong>toString</strong>
                            </td>
                            <td> </td>
                            <td>Returns a representation of the Element as a String.</td>
                        </tr>
                    </tbody>
                </table>
                <p>
					For more detail go
                    <a href="http://www.jdom.org/docs/apidocs/org/jdom/Element.html" target="_blank">here</a>
                    .
                </p>
                <p>Now let's see a small tree modification example. It will seem simple after what we've done up till now but that's the aim:</p>
                <p>I want to show that JDOM is simple above all else, we're going to modify the content of our Example 2.xml file (from 3.1) by deleting all firstname Elements from our tree.</p>
                <textarea name="code" class="java">//Create a new JDOM3 class
					import java.io.*;
					import org.jdom.*;
					import org.jdom.input.*;
					import org.jdom.output.*;
					import java.util.List;
					import java.util.Iterator;
					public class JDom
					{
					static org.jdom.Document document;
					static Element root;
					public static void main(String[] args)
					{
					try
					{
					readFile("Exercice 2.xml");
					deleteElement("firstnames");
					saveFile("Exercice 2.xml");
					}
					catch(Exception e){}
					}
					//We parse the file and initialise the root
					//Of our tree
					static void readFile(String file) throws Exception
					{
					SAXBuilder sxb = new SAXBuilder();
					document = sxb.build(new File(file));
					root = document.getRootElement();
					}
					//We modify the Element
					static void supprElement(String element)
					{
					//First we list all the students
					List studentList = racine.getChildren("student");
					Iterator i = studentList.iterator();
					//We traverse the list with an iterator
					while(i.hasNext())
					{
					Element current = (Element)i.next();
					//If the student had the element in question we
					//apply the modifications
					if(current.getChild(element)!=null)
					{
					//We delete the element in question
					current.removeChild(element);
					//We rename the father element knowing the an XML tag
					//accepts neither spaces or special characteres.
					//"modified student" becomes "modified_student"
					current.setName("modified_student");
					}
					}
					}
					//We save our new tree in the original file
					//in a classic format
					static void saveFile(String file) throws Exception
					{
					XMLOutputter out = new XMLOutputter(Format.getPrettyFormat());
					sortie.out(document, new FileOutputStream(file));
					}
					}</textarea>
                <p>This is the content of "Example 2.xml" after compilation:</p>
                <textarea name="code" class="xml">
                    &lt;?xml version="1.0" encoding="UTF-8"?&gt;
                    <people>
                        <modified_student class="P2">
                            <name>CynO</name>
                        </modified_student>
                        <student class="P1">
                            <name>Superwoman</name>
                        </student>
                        <student class="P1">
                            <name>Don Corleone</name>
                        </student>
                    </people>
                </textarea>
                <h3>Transforming JDOM</h3>
                <h4>Going from DOM to JDOM and vis versa</h4>
                <p>Sometimes you will find yourself working with a DOM document.</p>
                <p>We will see how to transform a DOM document into a JDOM document and back. Here is a small function that receives in argument a DOM document and returns a JDOM document.</p>
                <textarea name="code" class="java">//To be compiled this function requires the following import
					//containing the DOMOutputter class
					import org.jdom.input.*;
					org.jdom.Document DOMtoJDOM(org.w3c.dom.Document documentDOM) throws Exception
					{
					//We use DOMOutputter for this transformation
					DOMBuilder builder = new DOMBuilder();
					org.jdom.Document documentJDOM = builder.build(documentDOM);
					return documentJDOM;
					}</textarea>
                <p>And here now is the opposite function that outputs JDOM from DOM.</p>
                <p>You will notice the similarity with the previous function.</p>
				<textarea name="code" class="java">//To compile this function requires the following import
					//containing the DOMOutputter class
					import org.jdom.output.*;
					org.w3c.dom.Document DOMtoJDOM(org.jdom.Document documentJDOM) throws Exception
					{
					//We use the DOMOutputter for this transformation
					DOMOutputter domOutputter = new DOMOutputter();
					org.w3c.dom.Document documentDOM = domOutputter.output(documentJDOM);
					return documentDOM;
					}</textarea>
                <h4>JDOM and XSLT</h4>
                <p>Thanks to the JAXP API and TraX it's very easy to do XSLT transformations on a JDOM document. In the following example we wil create a function that takes in argument a JDOM document and the name of an XSL file and creates in output a transformed XML file.</p>
                <textarea name="code" class="java">//To compile the functions requires the following imports
					import java.io.*;
					//JDOM
					import org.jdom.transform.*;
					import org.jdom.output.*;
					//TrAX
					import javax.xml.transform.*;
					import javax.xml.transform.stream.StreamSource;
					void outputXSLT(org.jdom.Document documentJDOMIn,String XSLFile)
					{
					//JDOMResult Document, result of the TraX transformation
					JDOMResult documentJDOMOut = null;
					//JDOM document after transformation
					org.jdom.Document result = null;
					try
					{
					//We define a transformer with the XSL source
					//that will define the transformation
					TransformerFactory factory = TransformerFactory.newInstance();
					Transformer transformer = factory.newTransformer(new StreamSource(XSLFile));
					//We transform the JDOMIn file with our transformer
					//The transform() method takes as argument the entry document associated to the transformer
					//And a JDOMResult document, result of the TraX transformation
					transformer.transform(new org.jdom.transform.JDOMSource(documentJDOMIn), documentJDOMOut);
					//To retrieve the result of this transformation
					//we use the getDocument() method.
					result = documentJDOMSortie.getDocument();
					//We create the XML document corresponding to the result
					XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());
					outputter.output(result, new FileOutputStream("result.xml"));
					}
					catch(Exception e){}
					}</textarea>
                <h3>Conclusion</h3>
                <p>You are now conscious of the usefulness of JDOM for treating XML data with Java.</p>
                <p>This API is however still young and evolving.</p>
                <p>To learn more about JDOM and stay informed I suggest the following sites:</p>
                <ul>
                    <li>
                        <a href="http://www.jdom.org" target="_blank">http://www.jdom.org</a>
                    </li>
                    <li>
                        <a href="http://java.sun.com" target="_blank">http://java.sun.com</a>
                    </li>
                    <li>
                        <a href="http://www.cafeconleche.org/" target="_blank">http://www.cafeconleche.org</a>
                    </li>
                </ul>
                <p>
                    I also wish to thank the
                    <a href="http://www.developpez.net/forums/viewforum.php?f=11" target="_blank">developpez.com forums</a>
                    for their help.
                </p>
                <p>
                    For any questions
                    <a href="mailto:nicolas.cynober@supinfo.com">nicolas.cynober@supinfo.com</a>
                </p>
            </div>
        </div>
    </body>
</html>

